﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Configuration;
using System.Collections.Specialized;

namespace GL_TakeEgg
{
    public partial class frmMain : Form
    {
        private ArrayList arrPoultry = new ArrayList();
        private ArrayList arrEggShit = new ArrayList();
        private Basket bk;
        private int markEgg = 0;
        private int markShit = 0;
        private int markFail = 0;
        private int markLevel = 0;

        private int fallerSpeed = 0;
        private int poultrySpeed = 0;
        private int fallerHeight = 0;
        private int fallerWidth = 0;
        private int poultryStartX = 0;
        private int poultryStartY = 0;
        private int poultryHeight = 0;
        private int poultryWidth = 0;
        private int poultryExcrete = 0;
        private int bossPeriod = 0;
        

        //private int speedFalling = 3;// = int.Parse(ConfigurationManager.AppSettings["FallerSpeed"]);
        private bool gameOver = false;
        private int timeGame = 0;
        private int counterSecond = 0;

        private bool moveLeft = true;
        private bool moveRigh = true;

        public frmMain()
        {
            InitializeComponent();
            GetConfig();
        }

        private void btnViews_Click(object sender, EventArgs e)
        {
            btnStart.Enabled = true;
            btnStop.Enabled = false;
            timerController.Stop();
        }

        private void GetConfig()
        {
            fallerSpeed = int.Parse(ConfigurationManager.AppSettings["FallerSpeed"]);
            fallerHeight = int.Parse(ConfigurationManager.AppSettings["FallerHeight"]);
            fallerWidth = int.Parse(ConfigurationManager.AppSettings["FallerWidth"]);
            poultrySpeed = int.Parse(ConfigurationManager.AppSettings["PoultrySpeed"]);
            poultryHeight = int.Parse(ConfigurationManager.AppSettings["PoultryHeight"]);
            poultryWidth = int.Parse(ConfigurationManager.AppSettings["PoultryWidth"]);
            poultryExcrete = int.Parse(ConfigurationManager.AppSettings["PoultryExcrete"]);
            poultryStartX = int.Parse(ConfigurationManager.AppSettings["PoultryStartX"]);
            poultryStartY = int.Parse(ConfigurationManager.AppSettings["PoultryStartY"]);
            bossPeriod = int.Parse(ConfigurationManager.AppSettings["BossPeriod"]);
        }

        private void timerController_Tick(object sender, EventArgs e)
        {
            for (int i = 0; i < arrEggShit.Count; i++)
            {
                ((Faller)arrEggShit[i]).Falling(333, 240, bk.X, bk.Y);
            }

            for (int i = 0; i < arrPoultry.Count; i++)
                ((Poultry)arrPoultry[i]).Crossing(240, poultryExcrete);

            timeGame ++;
            if (timeGame % 100 == 0)
            {
                counterSecond ++;
                lblCounter.Text = counterSecond.ToString();
                
                // Add time life for pountry
                for (int i = 0; i < arrPoultry.Count; i++)
                    ((Poultry)arrPoultry[i]).TimeLife += 1;
            }

            this.Refresh();
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            string configvalue1 = ConfigurationManager.AppSettings["FallerSpeed"];

            bk = new Basket();
            bk.Height = 30;
            bk.Width = 35;
            bk.Speed = 3;
            bk.X = 265;
            bk.Y = 290;

            btnStop.Enabled = false;
            arrPoultry.Add(NewPoultry(PoultryType.P_CHICKEN));

            timerController.Interval = 1;
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            btnStart.Enabled = false;
            btnStop.Enabled = true;
            picScreen.Focus();
            timerController.Start();
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.UserPaint, true);
        }

        private void picScreen_Paint(object sender, PaintEventArgs e)
        {
            if (gameOver)
            {
                Image img = GL_TakeEgg.Properties.Resources.gameover;
                e.Graphics.DrawImage(img, 250, 150, 80, 40);
                return;
            }

            for (int i = 0; i < arrPoultry.Count; i++)
            {
                ((Poultry)arrPoultry[i]).DrawFaller(e.Graphics);
            }

            for (int i = 0; i < arrEggShit.Count; i++)
            {
                ((Faller)arrEggShit[i]).DrawFaller(e.Graphics);
            }

            bk.DrawFaller(e.Graphics);
        }

        public void fl_touchBottom(object sender)
        {
            Faller fl = (Faller)sender;
            if (fl.FType != FallerType.SHIT)
            {
                markFail++;
                lblFail.Text = markFail.ToString();
                if (markFail == 3)
                {
                    GameOver();
                    return;
                }
            }
            arrEggShit.Remove(fl);
        }

        public void GameOver()
        {
            gameOver = true;
            btnStop.Enabled = false;
            timerController.Stop();
            arrEggShit.Clear();
            arrPoultry.Clear();
            this.Refresh();
        }

        public void fl_touchBasket(object sender)
        {
            Faller fl = (Faller)sender;
            switch (fl.FType)
            {
                case FallerType.EGG_BLUE:
                    markEgg += 1;
                    lblMark.Text = markEgg.ToString();
                    break;
                case FallerType.EGG_RED:
                    markEgg += 2;
                    lblMark.Text = markEgg.ToString();
                    break;
                case FallerType.EGG_PINK:
                    markEgg += 3;
                    lblMark.Text = markEgg.ToString();
                    break;
                case FallerType.EGG_GOLD:
                    markEgg += 5;
                    lblMark.Text = markEgg.ToString();
                    break;

                case FallerType.SHIT:
                    markShit++;
                    lblMarkShit.Text = markShit.ToString();
                    break;
            }

            if (markShit == 3)
            {
                GameOver();
                return;
            }

            // change speed when level up
            if (markEgg > 0 && markEgg % 20 == 0)
            {
                markLevel++;
                lblLevel.Text = markLevel.ToString();
                fallerSpeed += 1;
                // Chang speed for egg
                for (int i = 0; i < arrEggShit.Count; i++)
                    ((Faller)arrEggShit[i]).Speed = fallerSpeed;
            }

            arrEggShit.Remove(fl);
        }

        public void excreteEggShit(Point p,FallerType ft )
        {
            arrEggShit.Add(NewFaller(p,ft));
        }

        private Poultry NewPoultry(PoultryType pt)
        {
            Poultry npt;
            Random rd = new Random();
            int ran = rd.Next(0, 3);
            if (pt == PoultryType.P_CHICKEN)
                npt = new Poultry(PoultryType.P_CHICKEN);
            else if (pt == PoultryType.P_DUCK)
                npt = new Poultry(PoultryType.P_DUCK);
            else
                npt = new Poultry(PoultryType.P_GOOSE);

            npt.excreteEggShit += new Poultry.excreteEggShit_Handler(excreteEggShit);

            npt.BossPeriod = bossPeriod; // Chu ky de trung vang

            npt.Height = poultryHeight;
            npt.Width = poultryWidth;
            npt.Speed = poultrySpeed;
            npt.TimeExcrete = poultryExcrete;
            npt.X = poultryStartX;
            npt.Y = poultryStartY;
            return npt;
        }

        private Faller NewFaller(Point p, FallerType ft)
        {
            Faller fl = new Faller(ft);
            fl.touchBottom += new Faller.touchBottom_Handler(fl_touchBottom);
            fl.touchBasket += new Faller.touchBasket_Handler(fl_touchBasket);

            fl.Height = fallerHeight;
            fl.Width = fallerWidth;
            fl.Speed = fallerSpeed;
            fl.X = p.X;
            fl.Y = p.Y + 30;
            return fl;
        }

        private void picScreen_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                if (e.X > bk.X)
                {
                    int n = e.X - bk.X;
                    bk.Moving(240, n);
                }

                if (e.X < bk.X)
                {
                    int n = bk.X - e.X;
                    bk.Moving(240, -n);
                }
            }
        }

        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            switch (keyData)
            {
                case Keys.Left:
                    moveLeft = true;
                    moveRigh = false;
                    bk.Moving(240, -15);
                    break;
                case Keys.Right:
                    moveLeft = false;
                    moveRigh = true;
                    bk.Moving(240, 15);
                    break;
            }
            return base.ProcessCmdKey(ref msg, keyData);
        }

        private void btnNewGame_Click(object sender, EventArgs e)
        {
            timerController.Stop();
            arrEggShit.Clear();
            arrPoultry.Clear();
            this.Refresh();

            fallerSpeed = int.Parse(ConfigurationManager.AppSettings["FallerSpeed"]);
            btnStart.Enabled = true;
            gameOver = false;
            lblFail.Text = "0";
            lblLevel.Text = "0";
            lblMark.Text = "0";
            lblMarkShit.Text = "0";
            markEgg = 0;
            markFail = 0;
            markLevel = 0;
            markShit = 0;
            arrPoultry.Add(NewPoultry(PoultryType.P_CHICKEN));

        }

        private void frmMain_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.G: arrPoultry.Add(NewPoultry(PoultryType.P_CHICKEN)); break;
                case Keys.V: arrPoultry.Add(NewPoultry(PoultryType.P_DUCK)); break;
                case Keys.N: arrPoultry.Add(NewPoultry(PoultryType.P_GOOSE)); break;
            }
        }
    }
}
